package br.unisul.redeNeural;

import java.util.ArrayList;
import java.util.List;


/**
 * Configurações de uma {@link RedeNeural}, informando a quantidade de neuronios na camada de entrada,
 *  nas camadas intermediaria e na de saida. <br>
 *  Informa se a {@link RedeNeural} possui suporte a {@link Vies} e multicamadas, e tambem o valor da taxa de aprendizado.<br>
 * @version 1.0
 */
public class Configuracao implements java.io.Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7164606011994863463L;
	/**
	 * Quantidade de neuronios da camada de Saida
	 */
	private Integer quantidadeSaida;
	/**
	 * Quantidade de neuronios da camada de Entrada
	 */
	private Integer quantidadeEntrada;
	
	/**
	 * Rede tem suporte para vies
	 */
	private Boolean suportaVies;
	
	/**
	 * Configuracao da camada do meio
	 */
	private List<ConfiguracaoCamadaIntemediaria> camadasIntermediarias;
	
	/**
	 * <code>true</code> para aceitar redeNeural multicamadas;
	 */
	private Boolean multiCamadas;
	
	/**
	 * Taxa de aprendizado
	 */
	private Double taxaAprendizado = 1.0;
	
	
	/**
	 * Inicia a configuração informando a quantidade de neuronios na camada de entrada
	 * e na camada de saida. <br>
	 * Com a configuração default a {@link RedeNeural} não suportara o uso de {@link Vies},
	 * e tera um taxa de aprendizado igual a 1 e possui suporte para multiplas camadas
	 * @param qtdEntrada - neuronios da camada de entrada, dever ser maio que zero
	 * @param qtdSaida - neuronios da camda de saida, deve ser maior que zero
	 */
	public Configuracao(Integer qtdEntrada, Integer qtdSaida) {
		this.quantidadeEntrada = (qtdEntrada > 0)? qtdEntrada : 1 ;
		this.quantidadeSaida = (qtdSaida > 0)? qtdSaida : 1 ;
		camadasIntermediarias = new ArrayList<ConfiguracaoCamadaIntemediaria>();
		suportaVies = false;
		multiCamadas = true;
	}

	/**
	 * Metodo para adicionar uma camada Integerermediaria
	 * @param camadaIntermediaria - camada a ser adionada
	 * @return <code>true</code> ser for adicionado
	 */
	public Boolean addCamadaIntermediaria(ConfiguracaoCamadaIntemediaria camadaIntermediaria){
		return camadasIntermediarias.add(camadaIntermediaria);
	}

	/**
	 * Metodo para remover uma camada Integeremediaria
	 * @param camadaIntermediaria - camada a ser removida
	 * @return <code>true</code> ser for removida
	 */
	public Boolean removeCamadaIntermediaria(ConfiguracaoCamadaIntemediaria camadaIntermediaria){
		return camadasIntermediarias.remove(camadaIntermediaria);
	}
	
	/**
	 * 
	 * @return quantidade de camadas Integerermediarias adicionadas
	 */
	public Integer quantidadeCamadasIntermdiarias(){
		return camadasIntermediarias.size();
	}

	/**
	 * @return Quantidade de neuronios na cama de saida
	 */
	public Integer getQuantidadeSaida() {
		return quantidadeSaida;
	}


	/**
	 * @return quantidade de neuronios na camada de entrada
	 */
	public Integer getQuantidadeEntrada() {
		return quantidadeEntrada;
	}


	/**
	 * @return the camadasIntermediarias
	 */
	public List<ConfiguracaoCamadaIntemediaria> getCamadasIntermediarias() {
		return camadasIntermediarias;
	}

	/**
	 * @param camadasIntermediarias the camadasIntermediarias to set
	 */
	public void setCamadasIntermediarias(List<ConfiguracaoCamadaIntemediaria> camadasIntermediarias) {
		this.camadasIntermediarias = camadasIntermediarias;
	}

	/**
	 * @return the suportaVies
	 */
	public Boolean isSuportaVies() {
		return suportaVies;
	}

	/**
	 * @param suportaVies the suportaVies to set
	 */
	public void setSuportaVies(Boolean suportaVies) {
		this.suportaVies = suportaVies;
	}

	/**
	 * @return the multiCamadas
	 */
	public Boolean isMultiCamadas() {
		return multiCamadas;
	}

	/**
	 * @param multiCamadas the multiCamadas to set
	 */
	public void setMultiCamadas(Boolean multiCamadas) {
		this.multiCamadas = multiCamadas;
	}

	/**
	 * @return the taxaAprendizado
	 */
	public Double getTaxaAprendizado() {
		return taxaAprendizado;
	}

	/**
	 * a taxa de aprendizado deve ser setada entre um valor maior que 0  e 
	 * menor igual a 1
	 * @param taxaAprendizado - the taxaAprendizado to set
	 */
	public void setTaxaAprendizado(Double taxaAprendizado) {
		if(taxaAprendizado > 0 && taxaAprendizado <= 1)
			this.taxaAprendizado = taxaAprendizado;
	}
	
	@Override
	public String toString() {
		return "Quantidade Neuronios Entra: "+quantidadeEntrada+
		"\nQuantidade Neuronios Saidas: "+quantidadeSaida+
		"\nNeuronio Intermediarios: "+camadasIntermediarias+
		"\nTaxa de aprendizado: "+taxaAprendizado+
		"\nSuporta Vies: "+ suportaVies+
		"\nMultiplas Camadas: "+multiCamadas;
		
		
	}
	
	
}